
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.util.HashMap;
import java.util.Random;


public class PheromoneTrail implements PTrail {

	int zaehler=0;
	private static Random rand = new Random();
	private Color defColor = new Color(rand.nextInt(256), rand.nextInt(256), rand.nextInt(256));
	
	private static int length=15;
	
	private static int modifications[] = {20,-2,-2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
	
	private Point trace [];
	
	private int start;
	
	
	  private HashMap <Point,Integer> ueberschuss=new HashMap<Point, Integer>();

	
	private HashMap <Point,Integer> abnahme=new HashMap<Point, Integer>();

	private AntSimulation antSim;
	
	
	public HashMap<Point, Integer> getUeberschuss(){
		return this.ueberschuss;
	}
	
	public HashMap<Point, Integer> getAbnahme(){
		return this.abnahme;
	}
	
	public PheromoneTrail(AntSimulation as){
		antSim=as;
		trace=new Point[length];
//		modifications = new int[length];
//		for( int i = 0; i < length; i++ ){
//			modifications[i] = 0;
//		}
		start=0;
	}
	
	public void validate(Point p,int Futter){
		
		addPoint(p);
		
		modifications[0] = Futter;

		int k=0;
		int i=start-1;//aktueller startpunkt
		while(k<length){
			if(i<0)
				i=length-1;
			if(trace[i]==null){//falls ein Element nicht existiert,dann auch die dahinter nicht
				break;
			}
			
			if(antSim.getForestground()[trace[i].x][trace[i].y]<0){//negativer wert
				
			    
				if(antSim.getForestground()[trace[i].x][trace[i].y]==-255&&!(ueberschuss.containsKey(new Point(trace[i].x,trace[i].y)))){//falls feld schon auf 255 steht und ueberschuss punkt nicht enth???lt (das heisst feld ist voll)
					
					k++;
					i--;
					continue;
				}
				//wenn Ameise drauftsteht
				antSim.getForestground()[trace[i].x][trace[i].y]+=modifications[k]*(-1);
				
				if(antSim.getForestground()[trace[i].x][trace[i].y]>=0)//damit die ameise auch stehen bleibt
					antSim.getForestground()[trace[i].x][trace[i].y]=-1;
				//System.out.println(antSim.getForestground()[trace[i].x][trace[i].y]);
				/*if(antSim.getForestground()[trace[i].x][trace[i].y]<-255)//falls zu gross
					antSim.getForestground()[trace[i].x][trace[i].y]=-255;*/
				if(antSim.getForestground()[trace[i].x][trace[i].y]<=-255&&k==0){//erster punkt eigentlich immer negativ
				
					
					antSim.getForestground()[trace[i].x][trace[i].y]=ueberlauf(trace[i],modifications[k])*(-1);//da positiver wert zurueck gegeben wird(255)
				}
				
				if(ueberschuss.containsKey(new Point(trace[i].x,trace[i].y))&&k>=1){
					
					antSim.getForestground()[trace[i].x][trace[i].y]=ueberlauf2(trace[i],modifications[k])*(-1);//da positiver wert zurueck gegeben wird(255)
					
				}
			}//if
			else{//positiver wert
				
				
				if(antSim.getForestground()[trace[i].x][trace[i].y]==255&&!(ueberschuss.containsKey(new Point(trace[i].x,trace[i].y)))){//falls feld schon auf 255 steht und ueberschuss punkt nicht enth???lt (das heisst feld ist voll)
					
					k++;
					i--;
					continue;
				}
				antSim.getForestground()[trace[i].x][trace[i].y]+=modifications[k];
				if(antSim.getForestground()[trace[i].x][trace[i].y]<=0)//damit nicht aufeinmal ne ameise enteht
					antSim.getForestground()[trace[i].x][trace[i].y]=1;

				/*if(antSim.getForestground()[trace[i].x][trace[i].y]>255)//siehe oben
					antSim.getForestground()[trace[i].x][trace[i].y]=255;*/
				if(antSim.getForestground()[trace[i].x][trace[i].y]>=255&&k==0){//erster punkt eigentlich immer negativ
					
					antSim.getForestground()[trace[i].x][trace[i].y]=ueberlauf(trace[i],modifications[k]);//(immer 255)
				}
				
				if(ueberschuss.containsKey(new Point(trace[i].x,trace[i].y))&&k>=1){
					
					antSim.getForestground()[trace[i].x][trace[i].y]=ueberlauf2(trace[i],modifications[k]);
					
				}
			}//else
			
			k++;
			i--;
			
		}//while
		
		
		
	}
	
	public int ueberlauf(Point p,int mod){
		
	    if(!ueberschuss.containsKey(p)){//falls noch nicht enthalten
	    	ueberschuss.put(p,Math.abs(antSim.getForestground()[p.x][p.y]));//es wird mit positiven werten gearbeitet
	    }
	    else{
	    	int temp=ueberschuss.get(p)+mod;
	    	ueberschuss.put(p,temp);
	    }
	    
	    int sum=0;
		for(int i=1;i<modifications.length;i++){//alle dekremntierungen in modifications werden aufsummiert....
			sum+=modifications[i];
		}
		
	    if(!abnahme.containsKey(p)){//falls noch nicht enthalten
	    	abnahme.put(p,-sum);
	    }
	    else{
	    	int temp=abnahme.get(p)+sum;
	    	abnahme.put(p,temp);
	    }
	    
	    if(ueberschuss.get(p)+abnahme.get(p)>=255){//falls das feld voll ist
	    	
	    	//System.out.println("Ueberschuss removed:"+p.x+"und "+p.y);
	    	ueberschuss.remove(p);//bedingung in zeile 72 erfuellt
	    	abnahme.remove(p);
	    }
	    
	    return 255;
	
	}//ueberlauf1
	
	
	  public int ueberlauf2(Point p,int mod){
		  int temp=ueberschuss.get(p)-mod;//ueberschuss wird dekrementiert;
		  ueberschuss.put(p, temp);
		  temp=abnahme.get(p)-temp;//abnahme wird inkrementiert
		  abnahme.put(p,temp);
		  
		  if(ueberschuss.get(p)>=255){
			  return 255;
		  }
		  else{
			  temp=ueberschuss.get(p);
			  ueberschuss.remove(p);
			  abnahme.remove(p);
			  return temp;
		  }
		
	}//ueberlauf2
	  
	
	public void addPoint(Point p){
		/*for(int i=trace.length;i>0;i--){//alle Elemente werden eins nach hinten geschoben
			
			trace[i]=trace[i-1];
			
		}
		trace[0]=p;//Element wird an den Anfang hinzugefuegt
		
		*/
		//oder
		if(start==length)
			start=0;
		trace[start++]=p;
	}
	
	public void draw(Graphics g){
		
		for(int i=0;i<length;i++){
			if(trace[i]==null)
				break;
			int tmp = antSim.getForestground()[trace[i].x][trace[i].y];

			if(tmp>0){
				Color tmpColor = new Color( -tmp/2+154, 205-tmp/2, 50+tmp/2 );
				g.setColor(tmpColor);
				g.fillRect(trace [i].x, trace[i].y, 1	, 1);
//				AntSimulation.underlayer.setRGB(trace[i].x, trace[i].y, defColor.getRGB());
			}
		}
//		g.setColor(Color.black);
	}

}
